import { 
    Component,
    UniformInjector,
 } from 'kokomi.js';
import type { Base } from 'kokomi.js';
import { 
    PlaneGeometry,
    SphereGeometry,
    ShaderMaterial,
    Mesh,
    Color,
} from 'three';
import Debug from '../Debug';
import testObjectVertexShader from "../shaders/testObject/vert.glsl";
import testObjectFragmentShader from "../shaders/testObject/frag.glsl";
import type Experience from "../Experience";

export default class TestObject extends Component{
    declare base: Experience;

    public materail: ShaderMaterial;
    public mesh: Mesh;
    public uj: UniformInjector;

    constructor(base: Base){
        super(base);

        const params = {
            uDistort: {
                value: 1,
            },
            uFrequency: {
                value: 1,
            },
            uFresnelIntensity: {
                value: 0.02,
            },
            uLightIntensity: {
                value: 0.9,
            },
            uLight2Intensity: {
                value: 0.9,
            }
        };

        const colorParams = {
            themeColor: '#070618',
            lightColor: '#4cc2e9',
            light2Color: '#9743fe',
        };
        this.base.scene.background = new Color(colorParams.themeColor);

        const RADIUS = 1.001;
        const SEGMENTS = 256.0001;

        const geometry = new SphereGeometry(RADIUS, SEGMENTS, SEGMENTS);
        // const geometry = new PlaneGeometry(
        //     RADIUS * 2,
        //     RADIUS * 2,
        //     SEGMENTS,
        //     SEGMENTS,
        // );

        const material = new ShaderMaterial({
            vertexShader: testObjectVertexShader,
            fragmentShader: testObjectFragmentShader,
            defines: {
                RADIUS,
                SEGMENTS,
            },
        });
        this.materail = material;

        const mesh = new Mesh(geometry, material);
        this.mesh = mesh;

        const uj = new UniformInjector(this.base);
        this.uj = uj;
        material.uniforms = {
            ...material.uniforms,
            ...uj.shadertoyUniforms,
            ...params,
            uThemeColor: {
                value: new Color(colorParams.themeColor),
            },
            uLightColor: {
                value: new Color(colorParams.lightColor),
            },
            uLight2Color: {
                value: new Color(colorParams.light2Color),
            }
        };


        const debug = this.base.debug as any as Debug;
        if(debug?.active){
            const debugFolder = debug.ui?.addFolder('testObject');
            debugFolder?.add(params.uDistort, 'value')
                .min(0)
                .max(2)
                .step(0.01)
                .name('distort');
            
            debugFolder?.add(params.uFrequency, 'value')
                .min(0)
                .max(2)
                .step(0.01)
                .name('frequency');

            debugFolder?.addColor(colorParams, 'themeColor').onChange((val: string) => {
                material.uniforms.uThemeColor.value = new Color(val);
                this.base.scene.background = new Color(val);
            });

            debugFolder?.addColor(colorParams, 'lightColor').onChange((val: string) => {
                material.uniforms.uLightColor.value = new Color(val);
            });
            debugFolder?.addColor(colorParams, 'light2Color').onChange((val: string) => {
                material.uniforms.uLight2Color.value = new Color(val);
            });

            debugFolder?.add(params.uFresnelIntensity, 'value')
             .min(0)
             .max(1)
             .step(0.01)
             .name('fresnelIntensity');

             debugFolder?.add(params.uLightIntensity, 'value')
             .min(0)
             .max(1)
             .step(0.01)
             .name('lightIntensity');
        }

    }

    addExisting(): void {
        this.container.add(this.mesh);
    }

    update(){
        this.uj.injectShadertoyUniforms(this.materail.uniforms);
    }
}